package cn.xiaopengstack.domain.strategy.service.rule.chain.factory;

import cn.xiaopengstack.domain.strategy.model.entity.StrategyEntity;
import cn.xiaopengstack.domain.strategy.model.entity.UserEntity;
import cn.xiaopengstack.domain.strategy.repository.IStrategyRepository;
import cn.xiaopengstack.domain.strategy.service.rule.chain.ILogicChain;
import cn.xiaopengstack.types.common.Constants;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Stream;

/**
 * @author jiangyangang
 */
@Component
@Slf4j
public class DefaultLogicChainFactory {

    private final Map<LogicModel, ILogicChain> logicChainMap = new LinkedHashMap<>();

    public DefaultLogicChainFactory(Map<String, ILogicChain> logicChainMap) {

        logicChainMap.forEach((k, v) -> {
            this.logicChainMap.put(LogicModel.of(k), v);
        });
    }

    public ILogicChain openLogicChain(StrategyEntity strategyEntity) {
        String ruleModel = strategyEntity.getRuleModels();
        String[] ruleModels = ruleModel.split(Constants.SPLIT);

        if (CollectionUtils.isEmpty(Arrays.asList(ruleModels))) {
            return logicChainMap.get(LogicModel.RULE_DEFAULT);
        }

        // 装配责任链
        ILogicChain iLogicChain = logicChainMap.get(LogicModel.of(ruleModels[0]));
        ILogicChain current = iLogicChain;
        for (int i = 1; i < ruleModels.length; i++) {
            if (Objects.isNull(logicChainMap.get(LogicModel.of(ruleModels[i])))) {
                continue;
            }
            current =  current.appendChain(logicChainMap.get(LogicModel.of(ruleModels[i])));
        }

        current.appendChain(logicChainMap.get(LogicModel.RULE_DEFAULT));
        return iLogicChain;
    };

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    public static class StrategyAwardVO {
        /** 抽奖奖品ID - 内部流转使用 */
        private Integer awardId;
        /**
         * 策略ID
         */
        private Long strategyId;
        /**
         * 在哪个节点被拦截
         * LogicModel
         */
        private LogicModel takeOverRule;
    }

    @Getter
    @AllArgsConstructor
    public enum LogicModel {
        RULE_DEFAULT("rule_default", "默认抽奖"),
        RULE_BLACKLIST("rule_blacklist", "黑名单抽奖"),
        RULE_WEIGHT("rule_weight", "权重规则"),
        ;

        private final String code;
        private final String info;

        public static LogicModel of(String code) {
            return Stream.of(LogicModel.values()).filter(logicEnumCode -> logicEnumCode.getCode().equals(code)).findFirst().orElse(null);
        }

    }

}
